#include "gtest/gtest.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "test_main.h"

extern "C" {
#include "webcli.h"
#include "thread_intf.h"
#include "log_intf.h"
}

class WebcliTest : public testing::Test {
protected:
    void SetUp() override {
        // 初始化日志模块以便查看测试输出
        log_init();
    }
    void TearDown() override {
        log_deinit();
    }
};

TEST_F(WebcliTest, InitDeinitSuccess) {
    // 测试初始化
    EXPECT_EQ(WebcliInit(), RETURN_OK);
    
    // 验证线程池已创建
    extern TPool* g_webcliThreadPool;
    EXPECT_NE(g_webcliThreadPool, nullptr);
    
    // 测试销毁
    WebcliDeinit();
    EXPECT_EQ(g_webcliThreadPool, nullptr);
}

TEST_F(WebcliTest, EventLoopTaskAdded) {
    // 初始化模块
    ASSERT_EQ(WebcliInit(), RETURN_OK);
    
    // 获取线程池引用
    extern TPool* g_webcliThreadPool;
    
    // 验证事件循环是否启动
    // 通过检查线程池指针是否非空来验证
    EXPECT_NE(g_webcliThreadPool, nullptr);
    
    // 清理
    WebcliDeinit();
}

TEST_F(WebcliTest, DoubleInitHandling) {
    // 第一次初始化应该成功
    EXPECT_EQ(WebcliInit(), RETURN_OK);
    
    // 第二次初始化应该失败或返回已初始化状态
    EXPECT_NE(WebcliInit(), RETURN_OK);
    
    // 清理
    WebcliDeinit();
}

TEST_F(WebcliTest, DISABLED_SocketListenTest) {
    // 首先检查7000端口是否可用
    int testSock = socket(AF_INET, SOCK_STREAM, 0);
    ASSERT_GE(testSock, 0);

    struct sockaddr_in testAddr;
    memset(&testAddr, 0, sizeof(testAddr));
    testAddr.sin_family = AF_INET;
    testAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    testAddr.sin_port = htons(6789);

    // 尝试绑定测试端口
    int bindRet = bind(testSock, (struct sockaddr*)&testAddr, sizeof(testAddr));
    if (bindRet < 0) {
        close(testSock);
        FAIL() << "Port 6789 is already in use, cannot run test";
    }
    close(testSock);

    // 初始化模块
    ASSERT_EQ(WebcliInit(), RETURN_OK);

    // 等待协程启动
    sleep(1);

    // 尝试连接7000端口
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    ASSERT_GE(sockfd, 0);

    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(6789);
    inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);

    // 测试连接
    int ret = connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
    EXPECT_EQ(ret, 0) << "Failed to connect to port 6789";

    // 验证socket状态
    int optval;
    socklen_t optlen = sizeof(optval);
    getsockopt(sockfd, SOL_SOCKET, SO_ACCEPTCONN, &optval, &optlen);
    EXPECT_EQ(optval, 1) << "Socket is not in listening state";

    // 清理
    close(sockfd);
    WebcliDeinit();
}
